using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;

using Castle.Windsor.Configuration.Interpreters;
using Castle.MicroKernel;
using Castle.Windsor;
using Castle.Core.Resource;
using Redboil.Bfp.Core;

namespace Redboil.Bfp.Core {
    /// <summary>
    /// The IoC container that provides interface to find Service.
    /// </summary>
    public sealed class Container {
        private XmlInterpreter interpreter;
        private WindsorContainer windsor;
        private static readonly Container instance = new Container();

        /// <summary>
        /// Get the instance of the IoC Container.
        /// </summary>
        public static Container Instance {
            get { return instance; }
        }

        /// <summary>
        /// Get the instance of the MicroKernel.
        /// </summary>
        public IKernel Kernel { get; private set; }

        private Container() {
            try {
                interpreter = new Castle.Windsor.Configuration.Interpreters.XmlInterpreter("Castle.config");
                windsor = new WindsorContainer(interpreter);
                Kernel = windsor.Kernel;
            }
            catch (ResourceException E) {
                throw E;
                //ProcessBizException.ProcessConfigurationException(E);
            }
            catch (ComponentNotFoundException E) {
                throw E;
            }
            catch (ComponentRegistrationException E) {
                throw E;
            }
            catch (KernelException E) {
                throw E;
            }
        }

        /// <summary> 
        /// Returns a component instance by the type of service. 
        /// </summary>
        /// <returns></returns>
        public T Resolve<T>() {
            return (T)Kernel.Resolve<T>();
        }

        /// <summary> 
        /// Release resource that be container used. 
        /// <see cref="IKernel"/>
        /// </summary>
        public void Dispose() {
            Kernel.Dispose();
        }
    }
}